package com.woniuxy.zuul.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.woniuxy.commons.dto.AuthDto;
import com.woniuxy.commons.entity.ResponseEntity;
import com.woniuxy.commons.service.RemoteAuthService;
import com.woniuxy.commons.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;


/**
 * @Auther: 王敞
 * @E-mail： 365799712@qq.com
 * @Date: 2020/07/24/12:02
 * @Description:
 */
@Component
public class CustomZuulFilter extends ZuulFilter {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private RemoteAuthService remoteAuthService;
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return -10000;
    }

    @Override
    public boolean shouldFilter() {
        //上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        //获取request
        HttpServletRequest request = context.getRequest();
        //获取uri
        String uri = request.getRequestURI();
        //判断
        if(uri.endsWith(".html")){
            return false;
        }
        if(uri.endsWith("addImage")){
            return false;
        }
        if (uri.startsWith("/learnmap")) {
            return true;
        }else if(uri.startsWith("/exam")){
            return true;
        }else if(uri.startsWith("/user")){
            return true;
        }
        else if(uri.startsWith("/course")){
            return true;
        }
        return false;
    }


    @Override
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
        // 获取request
        HttpServletRequest request = context.getRequest();
        // 获取refreshToken
        String refreshToken = request.getHeader("refreshToken");
        // 获取response
        HttpServletResponse response = context.getResponse();
        // 判断
        if (refreshToken == null || refreshToken.length() == 0) {
            goLogin(context, response);
            return null;
        }
        // 判断refreshToken作为key,token为null
        if(redisTemplate.opsForHash().entries(refreshToken) == null) {
            goLogin(context, response);
            return null;
        }
        // 获取token，对token进行校验
        String token = request.getHeader("token");
        //token非法去登陆
        if(JwtUtil.validate(token) == JwtUtil.STATUS_ERROR) {
            goLogin(context, response);
            return null;
        }
        //token过期，刷新
        if (JwtUtil.validate(token) == JwtUtil.STATUS_EXPIRE) {
            AuthDto authDto =remoteAuthService.refresh(refreshToken);
            //200 刷新成功，refreshToken
            response.setContentType("application/json;charset=utf-8");
            //返回数据写在response中，但后面代码会继续执行
            response.setHeader("token", authDto.getToken());
        }
        //其余，不作处理
        return null;
    }
    /**
     * 去登陆方法
     * @param context
     * @param response
     * @author 王敞
     */
    private void goLogin(RequestContext context, HttpServletResponse response) {
        // 请求结束
        context.setSendZuulResponse(false);
        //
        response.setContentType("application/json;charset=utf-8");
        ResponseEntity<Void> responseDto = new ResponseEntity<Void>();
        responseDto.setCode(302).setMessage("登录");
        try {
            String data = new ObjectMapper().writeValueAsString(responseDto);
            response.getWriter().write(data);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
